home *** CD-ROM | disk | FTP | other *** search
/ Gekkan Dennou Club 147 / Gekkan Dennou Club - 2000.8 Vol. 147 (Japan).7z / Gekkan Dennou Club - 2000.8 Vol. 147 (Japan) (Track 1).bin / tools / ask / ksd / source / ksd.s < prev    next >
Text File  |  1998-10-01  |  42KB  |  1,523 lines

  1. *********************************************************************
  2. *          キー入力・シミュレート・ドライバー
  3. *             KSD V1.7
  4. *        Copyright (C) 1997,98 by AIG-Soft
  5. *********************************************************************
  6.  
  7.     .include    defines.mac
  8.     .include    fefunc.dis
  9.     .include    pspdef.mac
  10.     .include    skey.mac
  11.     .include    ksd.mac
  12.  
  13. * モード定数(0および正負は変えないこと)
  14. MD_OnceActive    equ    -2
  15. MD_BuffActive    equ    -1
  16. MD_Active    equ    0
  17. MD_Pause    equ    1
  18. MD_Stop        equ    2
  19.  
  20. *********************************************************************
  21. *    常駐ルーチン
  22. *********************************************************************
  23.  
  24.     .text
  25.     .even
  26. DevHead:    * デバイスヘッダー(ファイル先頭に必要)
  27.     .dc.l    -1            * next device none
  28.     .dc.w    %11000000_00000000    * char device/IOCTRL ok/Cooked
  29.     *        ??         ? 0000
  30.     .dc.l    Dev_start
  31.     .dc.l    Dev_main
  32. DevName    .dc.b    '@KEY    '        * devive name
  33. *         12345678        * /Kで@KSDになる
  34. KSDsym    .dc.b    'AIG-KSD '        * KSD Symbol
  35.  
  36. *********************************************************************
  37. * ワーク1
  38. *********************************************************************
  39. * 外部プログラム定義(この位置は変更しないこと;ksd.macでKSD_APIの算出に使っている)
  40. * デフォルトのトップはSHIFT+登録でキーバッファー読みだし
  41.  
  42.     .even
  43. ExtFunc    .dc.b    .low.(SKtou>>8)    * 起動キー(スキャンコード)
  44.                 * $00なら起動しない(登録はされている)
  45.                 * $1d=CRはSuperEDには使えない
  46.     .dc.b    SKsft        * シフト状態(B_SFTSNS、ただしbit0-3のみ有効)
  47.                 * 0も一応可能(お勧めはしない)
  48.     .dc.l    OnceActive    * 起動アドレス
  49.     .dc.l    0        * ここに次のテーブルアドレスを書くとリンクする(V1.1)
  50.  
  51. *--------------------------------------------------------------------
  52. * 固定値(この位置は変更しないこと;ksd.macで参照している)
  53.  
  54. API:    .dc.l    APImain        * APIアドレス
  55. Ver1:    .dc.b    1        * バージョン番号整数桁
  56. Ver2:    .dc.b    7        * バージョン番号小数桁:01-09は表せない
  57.     .even
  58.  
  59. *--------------------------------------------------------------------
  60. * 変化値
  61.  
  62. ProcAD    .dc.l    0    * このプロセスの先頭アドレス(!=DevHead/常駐解除時に必要)
  63. Dev_A5    .dc.l    0    * a5 save work
  64. *
  65. Kbuff    .dc.l    0    * Key Buffer Address
  66. KBsize    .dc.l    0    * Key Buffer Size
  67. rp    .dc.l    0    * Key Buffer Read Pointer
  68. wp    .dc.l    0    * Key Buffer Write Pointer
  69. Key1    .dc.l    0    * 起動キー保護のためなど
  70. *
  71. fdev    .dc.b    0    * device driver flag : 0:常駐プログラム , <>0:デバイスドライバー
  72. Kbmode    .dc.b    0    * Kbuffの位置 : =0:プログラム後部 , <>0:高位メモリー
  73. mode    .dc.b    0    * 動作モード  : =0:活動中 , 1:休止 , 2:完全停止
  74.             *               =-1:外部プログラム起動無し活動 , =-2:一時活動
  75. SnsSkip    .dc.b    0    * B_KEYSNSをスキップする回数
  76. Emode    .dc.b    0    * 書込みFull時の処理 : 0:古いデータを消す , <>0:書き込めない部分は無視
  77. JLock    .dc.b    0    * 常駐解除ロックカウント : =0:解除可能 , >0:解除不可
  78.     .even
  79.  
  80. *********************************************************************
  81. * APIルーチン
  82. *********************************************************************
  83.  
  84. APImain:
  85. * コマンドサーチ&実行
  86. * d0.b=コマンド(未定義コマンドは:アルファベット->無視、数字->暴走)
  87. * d0.l以外は保存
  88. * あらかじめスーパーバイザーモードにしてから呼び出すこと
  89. * B_系以外はユーザーモードでもよいが、device=で組み込まれている時は
  90. * ユーザーモードではアクセス出来ないから。
  91.     * APImain内ではd0,d7,a0,a1以外破壊しないこと
  92.     * d1-d6,a2-a6は引数として予約
  93.     movem.l    d1-d7/a0-a6,-(sp)
  94.     cmp.b    #'A',d0            * アルファベットコマンド?
  95.     bcc    AlphaCOM        * Yes
  96.     * 数値コマンド
  97.     moveq.l    #0,d7
  98.     move.b    d0,d7            * .b -> .l
  99.     add.w    d7,d7            * *2 (for word)
  100.     move.w    CtableN(pc,d7.w),d7    * コマンドアドレス
  101.     bra    1f
  102. *
  103. AlphaCOM:    * アルファベットコマンド
  104.     lea    CtableC(pc),a0        * コマンド文字群
  105.     lea    CtableA-2(pc),a1    * コマンドアドレス
  106. @@:    addq.w    #2,a1
  107.     move.b    (a0)+,d7
  108.     beq    2f            * end of table
  109.     cmp.b    d7,d0            * 一致?
  110.     bne    @b            * NO -> next command
  111.     * コマンド発見
  112.     move.w    (a1),d7            * offset
  113. 1:    *
  114.     moveq.l    #0,d0            * for .b/.w -> .l
  115.     jsr    DevHead(pc,d7.w)    * 実行
  116.     *
  117. 2:    movem.l    (sp)+,d1-d7/a0-a6
  118.     rts
  119. *
  120.     * コマンドジャンプアドレス
  121. CtableN:    * 数値コマンド(0~番号順)
  122.     .dc.w    API_reserve-DevHead    * 未定義
  123.     .dc.w    API_CheckFull-DevHead    * ->d0.l
  124.     .dc.w    API_CheckEmpty-DevHead    * ->d0.l
  125.     .dc.w    API_Rcheck-DevHead    * ->d0.b
  126.     .dc.w    API_Read-DevHead    * <-a2,d1.l ->d0.l
  127.     .dc.w    API_Write-DevHead    * <-a2,d1.l ->d0.l
  128.     .dc.w    API_ReadMode-DevHead    * ->d0.l
  129.     .dc.w    API_ReadVer-DevHead    * ->d0.w
  130.     .dc.w    API_ReadSize-DevHead    * ->d0.l
  131.     .dc.w    API_ReadFree-DevHead    * ->d0.l
  132.     .dc.w    API_LinkEFunc-DevHead    * <-a2 ->d0.l
  133.     .dc.w    API_UnlinkEFunc-DevHead    * <-a2 ->d0.l
  134.     .dc.w    API_JLock-DevHead    * ->d0.b
  135.     .dc.w    API_JUnlock-DevHead    * ->d0.b
  136.     .dc.w    API_Read1-DevHead    * ->d0.l
  137.     .dc.w    API_Write1-DevHead    * <-d1.b ->d0.l
  138.     .dc.w    NonInp-DevHead        * ->d0.l
  139.     .dc.w    NonSns-DevHead        * ->d0.l
  140.     .dc.w    NonSft-DevHead        * ->d0.l
  141.     .dc.w    API_ExecEFunc-DevHead    * <-a2 ->d0.l
  142.     .dc.w    API_DevNameA-DevHead    * <-a2            v1.7
  143.  
  144. CtableA:    * アルファベットコマンド(下のアルファベットコマンド表と対)
  145.     .dc.w    Clear-DevHead        * なし
  146.     .dc.w    Pause-DevHead        * なし
  147.     .dc.w    Active-DevHead        * なし
  148.     .dc.w    BuffActive-DevHead    * なし
  149.     .dc.w    OnceActive-DevHead    * なし
  150.     .dc.w    Stop-DevHead        * なし
  151.     .dc.w    WFMusi-DevHead        * なし
  152.     .dc.w    WFFull-DevHead        * なし
  153.  
  154. CtableC:    * アルファベットコマンド名(良く使う順にしておくのがよい)
  155.     .dc.b    KSD_Clear
  156.     .dc.b    KSD_Pause
  157.     .dc.b    KSD_Active
  158.     .dc.b    KSD_BuffActive
  159.     .dc.b    KSD_OnceActive
  160.     .dc.b    KSD_Stop
  161.     .dc.b    KSD_WFMusi
  162.     .dc.b    KSD_WFFull
  163.     .dc.b    0            * end of table
  164.  
  165.     .even
  166.  
  167. *********************************************************************
  168. * 基本内部ルーチン1:内部状態設定/参照
  169. *********************************************************************
  170.  
  171. API_ReadVer:    * バージョン読みだし
  172.     move.w    Ver1(pc),d0        * d0.h.b=整数,d0.l.b=小数
  173. API_reserve:    * 未定義コマンド
  174.     rts
  175.  
  176. *--------------------------------------------------------------------
  177.  
  178. API_ReadMode:    * 内部状態読みだし
  179. * 'E/F','O/B/A/P/S'
  180. * d0.l,d1.l,a0破壊
  181.     move.l    #$2020_0000,d0    * ' ',' '
  182.     * 書き込みfull時
  183.     move.l    #KSD_WFMusi.shl.16+KSD_WFFull,d1    * 無視/消す
  184.     tst.b    Emode
  185.     beq    @f        * 消す
  186.     swap    d1        * 消す/無視
  187. @@:    move.b    d1,d0        * 2020_00FE
  188.     lsl.w    #8,d0        * 2020_FE00
  189.     * 内部状態
  190.     moveq.l    #0,d1        * for .b->.w
  191.     move.b    mode(pc),d1    * -2,-1,0,1,2
  192.     addq.b    #2,d1        * 0,1,2,3,4
  193.     lea    ModeChar(pc),a0
  194.     move.b    (a0,d1.w),d0    * 2020_FEAP
  195.     rts
  196.  
  197.     * 動作状態キャラクター(mode+2=0~順)
  198. ModeChar    .dc.b    KSD_OnceActive,KSD_BuffActive,KSD_Active,KSD_Pause,KSD_Stop
  199.     .even
  200.  
  201. *--------------------------------------------------------------------
  202.  
  203. API_ReadSize:    * バッファーサイズ読みだし
  204.     move.l    KBsize(pc),d0
  205.     rts
  206.  
  207. API_ReadFree:    * バッファーフリーサイズ読みだし
  208. * d0.l,d1.l,d2.l破壊
  209.     move.l    KBsize(pc),d0    * KBsize
  210.     subq.l    #1,d0        * -1
  211.     move.l    rp(pc),d1
  212.     move.l    wp(pc),d2
  213.     sub.l    d2,d0        * -wp
  214.     cmp.l    d1,d2        * wp>rp?
  215.     bcc    @f
  216.     * wp<rp
  217.     sub.l    d1,d0        * -rp
  218.     rts
  219.  
  220. @@:    * wp>=rp
  221.     add.l    d1,d0        * +rp
  222.     rts
  223.  
  224. *--------------------------------------------------------------------
  225.  
  226. WFFull:    * 書き込みFull時:古いデータを消す
  227.     clr.b    Emode
  228.     rts
  229. *
  230. WFMusi:    * 書き込みFull時:無視
  231.     st.b    Emode
  232.     rts
  233.  
  234. *--------------------------------------------------------------------
  235.  
  236. Stop:    * KSDを停止させる
  237.     * 外部プログラム起動も不可能
  238.     move.b    #MD_Stop,mode
  239.     rts
  240. *
  241. Pause:    * 一時的に本来のキー入力へ戻す(休止)
  242.     * 外部プログラム起動は可能
  243.     move.b    #MD_Pause,mode
  244.     rts
  245. *
  246. OnceActive:    * KSDを一時的に有効にする(キーバッファー内容がある内だけ)
  247.     move.b    #MD_OnceActive,mode
  248.     rts
  249. *
  250. BuffActive:    * 外部プログラム起動は不可活動状態
  251.     st.b    mode        * mode=$ff=-1=MD_BuffActive
  252.     rts
  253. *
  254. Active:    * KSDを有効にする(活動状態)
  255.     clr.b    mode        * mode=0=MD_Active
  256.     rts
  257.  
  258. *--------------------------------------------------------------------
  259.  
  260. Clear:    * バッファークリア
  261.     clr.l    wp
  262.     clr.l    rp
  263.     *move.l    wp(pc),rp    * rp<-wp : 本当はこれでよい
  264.     rts
  265.  
  266. *--------------------------------------------------------------------
  267.  
  268. API_JLock:    * 常駐ロック
  269. * -> d0.b ロックカウント
  270. * 特にチェックはしていないが、.bの+領域0~128段のみ可能
  271.     move.b    JLock(pc),d0
  272.     addq.b    #1,d0
  273.     move.b    d0,JLock
  274.     rts
  275. *
  276. API_JUnlock:    * 常駐アンロック
  277. * -> d0.b ロックカウント
  278.     move.b    JLock(pc),d0
  279.     subq.b    #1,d0
  280.     bmi    @f        * マイナスにはしない
  281.     move.b    d0,JLock
  282. @@:    rts
  283.  
  284. *********************************************************************
  285. * 基本内部ルーチン2:バッファー状態読みだし
  286. *********************************************************************
  287.  
  288. API_CheckFull:            * バッファーフルチェック
  289. * d0.l:1=full , 0=ok
  290.     bsr.s    CheckFull    * d0/d1破壊
  291.     seq    d0
  292.     and.l    #1,d0        * d0.l = 0(ok),1(full)
  293.     rts
  294. *
  295. CheckFull:
  296. * eq=full , ne=ok
  297. * d0.l,d1.l 破壊
  298.     move.l    wp(pc),d0
  299.     move.l    KBsize(pc),d1    * KBsize
  300.     subq.l    #1,d1        *       -1
  301.     cmp.l    d0,d1        * wp==KBsize-1?
  302.     bne    @f        * no
  303.     * wp=KBsize-1のとき
  304.     tst.l    rp        * rp==0?
  305.     rts
  306.     *
  307. @@:    move.l    rp(pc),d1
  308.     subq.l    #1,d1
  309.     cmp.l    d1,d0        * wp==rp-1
  310.     rts
  311.  
  312. *--------------------------------------------------------------------
  313.  
  314. API_CheckEmpty:            * バッファー空チェック
  315. * d0.l:1=empty , 0=ok
  316.     bsr.s    CheckEmpty    * d0破壊
  317.     seq    d0
  318.     and.l    #1,d0        * d0.l = 0(ok),1(empty)
  319.     rts
  320. *
  321. CheckEmpty:
  322. * eq=empty , ne=ok
  323. * d0.l 破壊
  324.     move.l    wp(pc),d0
  325.     cmp.l    rp(pc),d0    * rp==wp?
  326.     rts
  327.  
  328. *********************************************************************
  329. * 基本内部ルーチン3:バッファー読み書き
  330. *********************************************************************
  331.  
  332. API_Rcheck:            * 先行入力
  333.     bsr    CheckEmpty    * 空?
  334.     bne    Rcheck        * -> d0.b(飛び先からrtsする),a0破壊
  335.     moveq.l    #0,d0        * 空=$00を返す
  336.     rts
  337. *
  338. Rcheck:                * rpを動かさないread
  339. * 空の時は呼び出さないこと
  340. * d0.b,a0 破壊
  341.     * d0.b <- Kbuff[rp]
  342.     move.l    Kbuff(pc),a0    * Kbuff
  343.     add.l    rp(pc),a0    * rp
  344.     move.b    (a0),d0        * Kbuff[rp]->d0.b
  345.     rts
  346.  
  347. *--------------------------------------------------------------------
  348.  
  349. IncPt    macro    point
  350. local    L1
  351.     addq.l    #1,d1        * p++
  352.     cmp.l    KBsize(pc),d1    * p>=KBsize?
  353.     bcs    L1        * no
  354.     moveq.l    #0,d1        * Yes : p=0
  355. L1:    move.l    d1,point
  356.     endm
  357. *
  358. *
  359. API_Read1:            * 1バイト読みだし
  360. * d0.l -> データ($00~$ff)/エラー(-1)
  361.     bsr    CheckEmpty    * 空? d0破壊
  362.     beq    ErrRW        * Yes
  363.     moveq.l    #0,d0        * for .b -> .l
  364.     bsr    Read        * d1,a0 破壊 -> d0.b(=.l)
  365.     rts
  366. *
  367. ErrRW:    moveq.l    #-1,d0        * バッファーが空
  368.     rts
  369. *
  370. *
  371. API_Read:            * バッファー内のみ読みだし
  372. * a2   <- read buffer
  373. * d1.l <- read要求 size
  374. * d0.l -> 実read size
  375.     move.l    d1,d3
  376.     beq    2f        * size=0 -> 何もしない
  377.     moveq.l    #0,d7        * size count=0
  378. @@:    bsr    CheckEmpty    * 空? d0破壊
  379.     beq    2f        * Yes
  380.     bsr    Read        * d0,d1,a0 破壊
  381.     addq.l    #1,d7        * read size
  382.     move.b    d1,(a2)+
  383.     subq.l    #1,d3
  384.     bne    @b        * dbraは.wループなので使えない
  385. 2:    move.l    d7,d0        * 実ReadSizeを返す
  386.     rts
  387. *
  388. Read:
  389. * 空の時は呼び出さないこと
  390. * d0.b,d1.l,a0 破壊
  391.     * d0.b <- Kbuff[rp++]
  392.     move.l    Kbuff(pc),a0    * Kbuff
  393.     move.l    rp(pc),d1    * rp
  394.     move.b    (a0,d1.l),d0    * Kbuff[rp]->d0.b
  395. RpINC:    * d1=rpのこと
  396.     IncPt    rp        * rp++
  397.     rts
  398.  
  399. *--------------------------------------------------------------------
  400.  
  401. API_Write1:            * 1バイト書き込み
  402. * d1.b <- data
  403. * d0.l -> 0=ok , -1=full
  404.     move.b    d1,d2        * push data
  405.     bsr    CheckFull    * full? (d0,d1 破壊)
  406.     beq    ErrRW        * Yes
  407.     move.b    d2,d0        * pop data
  408.     move.l    Kbuff(pc),a0    * Kbuff
  409.     bsr    Write
  410.     moveq.l    #0,d0
  411.     rts
  412. *
  413. API_Write:            * バッファー書き込み
  414. * a2   <- write buffer
  415. * d1.l <- write要求 size
  416. * d0.l -> 実write size
  417.     move.l    d1,d3
  418.     beq    5f        * size=0 -> 何もしない
  419.     moveq.l    #0,d7        * size count=0
  420.     move.l    Kbuff(pc),a0    * Kbuff
  421. @@:    bsr    CheckFull    * d0,d1 破壊
  422.     bne    2f        * fullでない
  423.     * Full:バッファーがいっぱい
  424.     tst.b    Emode        * 無視?
  425.     bne    5f        * Yes : 書き込めただけのサイズを持って返る
  426. 1:    * 古いデータを消して書き込む(実際にはrpを+1するだけ)
  427.     move.l    rp(pc),d1    * rp
  428.     bsr    RpINC        * rp++
  429. 2:    move.b    (a2)+,d0    * 書き込むデータ
  430.     bsr    Write
  431.     *
  432.     addq.l    #1,d7        * write size
  433. 3:    subq.l    #1,d3
  434.     bne    @b        * dbraは.wループなので使えない
  435. 5:    move.l    d7,d0        * 実WriteSizeを返す
  436.     rts
  437. *
  438. Write:
  439. * 空の時は呼び出さないこと
  440. * d0.b <- data
  441. * a0   <- Kbuff
  442. * d1.l 破壊
  443.     move.l    wp(pc),d1    * wp
  444.     move.b    d0,(a0,d1.l)    * d0.b->Kbuff[wp]
  445.     beq    @f        * $00の時はwpを動かさない=消す
  446.     IncPt    wp        * wp++
  447. @@:
  448.     rts
  449.  
  450. *********************************************************************
  451. * 基本内部ルーチン4:外部起動プログラム設定
  452. *********************************************************************
  453.  
  454. API_LinkEFunc:            * 外部起動プログラム追加(登録)
  455. * a2 <- テーブルadrs
  456. * -> d0.l : 0=出来た , 1=出来なかった
  457.     move.w    (a2),d0        * 起動キーセット
  458.     lea    ExtFunc(pc),a0    * リンクテーブル top
  459. @@:    cmp.w    (a0),d0        * 同じキーセットがある?
  460.     beq    1f        * Yes -> エラー
  461.     addq.w    #KSD_EF_Next,a0
  462.     move.l    (a0),d1        * next table adrs
  463.     beq    @f        * 最後->ここにつなぐ
  464.     * 最後ではない
  465.     move.l    d1,a0        * to next table
  466.     bra.s    @b
  467. *
  468. @@:    * 最後を見つけた
  469.     move.l    a2,(a0)        * link
  470.     moveq.l    #0,d0        * 正常登録の印
  471.     rts
  472.  
  473. 1:    * キーの重複があった
  474.     moveq.l    #1,d0        * エラーの印
  475.     rts
  476.  
  477. *--------------------------------------------------------------------
  478.  
  479. API_UnlinkEFunc:        * 外部起動プログラム解除
  480. * a2 <- テーブルadrs
  481. * -> d0.l : 0=出来た , 1=出来なかった
  482.     move.w    (a2),d0        * w.hb <- 起動キーScanCode / w.lb <- 起動キーShift状態
  483.     bsr    SearchEFKey    * キーサーチ
  484.     beq    @f        * そのキーがあった
  485.     * そのキーはなかった
  486.     moveq.l    #1,d0
  487.     rts
  488.  
  489. @@:    * そのキーはあった
  490.     cmp.l    a0,d1        * 一番最初?
  491.     beq    @f        * Yes : 一番最初のテーブルは消せないのでScanCode<-0だけする
  492.     * 一番最初以外のテーブル
  493.     * 解除するテーブルにつながっている次のテーブルを前のテーブルにつなぐ
  494.     move.l    d1,a1
  495.     move.l    KSD_EF_Next(a0),KSD_EF_Next(a1)
  496. @@:    clr.b    (a0)        * ScanCode<-0
  497.     moveq.l    #0,d0        * そのキーはあった
  498.     rts
  499.  
  500. *--------------------------------------------------------------------
  501.  
  502. API_ExecEFunc:            * 外部起動プログラム強制起動
  503. * a2 <- テーブルadrs
  504.     move.w    (a2),d0        * w.hb <- 起動キーScanCode / w.lb <- 起動キーShift状態
  505.     bsr    SearchEFKey    * 指定キーに相当する外部プログラム指定があるかを調べる
  506.     beq    @f        * そのキーがあった
  507.     * そのキーはなかった(起動できない)
  508.     moveq.l    #1,d0
  509.     rts
  510. *
  511. @@:    * 起動キーである
  512.     move.l    KSD_EF_Exec(a0),a0
  513.     jsr    (a0)        * 外部ルーチン(d0-d2/a0-a2以外は破壊しないこと)
  514.     moveq.l    #0,d0        * 起動出来た
  515.     rts
  516.  
  517. *--------------------------------------------------------------------
  518.  
  519. SearchEFKey:            * 指定キーに相当する外部プログラム指定があるかを調べる
  520. * d0.w.hb <- 起動キーScanCode(!=0)
  521. * d0.w.lb <- 起動キーShift状態
  522. * -> a0   : そのアドレス(a0=0:そのキーはなかった)
  523. * -> d1   : 前のテーブルのアドレス
  524. * eq=あった , ne=なかった
  525.     lea    ExtFunc(pc),a0        * リンクテーブル top
  526.     move.l    a0,d1            * 前のテーブル(先頭だけはそのテーブルそのもの)
  527. @@:    cmp.w    (a0),d0            * キーが一致?
  528.     beq    @f            * Yes -> end(eq)
  529.     * キーは不一致 -> 次のテーブルへ
  530.     move.l    a0,d1            * 前のテーブルアドレス保存
  531.     move.l    KSD_EF_Next(a0),a0    * to next table
  532.     cmp.l    #0,a0            * リンク最後?
  533.     bne    @b            * No
  534.     * リンクの最後まで行った
  535.     move.w    d0,d0            * neにする
  536. @@:    rts
  537.  
  538. *********************************************************************
  539. * 基本内部ルーチン5:デバイス名取得
  540. *********************************************************************
  541.  
  542. API_DevNameA:
  543. * a2 <- デバイス名格納エリア
  544.     lea    DevName(pc),a0
  545.     moveq.l    #8-1,d1        * -1 dbra
  546. @@:    move.b    (a0)+,d0
  547.     cmp.b    #' ',d0        * ' 'の直前まで
  548.     beq    2f
  549.     move.b    d0,(a2)+
  550.     dbra    d1,@b        * または8バイトまで
  551. 2:    clr.b    (a2)        * EOS
  552.     rts
  553.  
  554. *********************************************************************
  555. * キー入力シュミレート
  556. *   レジスター破壊はIOCS/DOSと同じ(d0.lのみ)
  557. *   この部分は常にスーパーバイザーモードで走る
  558. *********************************************************************
  559. * KFLUSH
  560.  
  561. k_flush:
  562.     cmp.b    #MD_Pause,mode
  563.     bge    k_flush0    * >=1 : 休止/停止中 -> 通常
  564.     bsr    CheckEmpty    * 空?
  565.     beq    k_flush0    * yes
  566.     * KSDキーバッファーあり
  567. @@:    * IOCSのキーバッファーのみクリア
  568.     bsr    NonSns        * B_KEYSNSの元のルーチン
  569.     tst.l    d0        * キーが押されている?
  570.     beq    @f        * No
  571.     bsr    NonInp        * 元のB_KEYINP
  572.     bra.s    @b        * IOCSキーバッファーを消す
  573. *
  574. @@:    move.b    #1,SnsSkip    * 次の1回のB_KEYSNSをスキップさせる
  575.                 * キーバッファークリアを回避するため
  576. k_flush0:
  577.     jmp    0.l        * 元のKFLUSHが入る
  578.                 * 飛び先でrtsする
  579.  
  580. KF_PATCH    equ    k_flush0+2
  581.  
  582. *--------------------------------------------------------------------
  583. * B_SFTSNS
  584.  
  585. KeySft:
  586.     cmp.b    #MD_Pause,mode
  587.     bge    NonSft        * >=1 : 休止/停止中 -> 通常
  588.     bsr    CheckEmpty    * 空?
  589.     beq    NonSft        * yes
  590.     * バッファー内容がある時
  591.     bsr    NonSft        * 元のB_SFTSNS
  592.     and.l    #$fff0,d0    * "OPT2|OPT1|CTRL|SHIFTは押されていない"とする
  593. ***    moveq.l    #0,d0        * "シフト系キーは押されていない"とする : これはASKで×
  594.     rts
  595.     *
  596. NonSft:    jmp    0.l        * 元のB_SFTSNSが入る
  597.                 * 飛び先でrtsする
  598.  
  599. SftPATCH    equ    NonSft+2
  600.  
  601. *--------------------------------------------------------------------
  602. * B_KEYSNS
  603.  
  604. KeySns:
  605.     cmp.b    #MD_Pause,mode
  606.     bge    NonSns        * >=1 : 休止/停止中 -> 通常
  607.     bsr    CheckEmpty    * 空?
  608.     beq    NonSns        * yes
  609.     * バッファーあり
  610.     tst.b    SnsSkip        * skip中?
  611.     beq    @f        * no
  612.     subq.b    #1,SnsSkip
  613.     moveq.l    #0,d0        * "キー入力はない"の印
  614.     rts
  615. @@:    *
  616.     move.l    a0,-(sp)
  617.     move.l    #$0001_0000|SKspc0,d0    * SPACE(scan code)
  618.     bsr    Rcheck        * -> d0.b : d0.l=$0001_35xx
  619.     move.l    (sp)+,a0
  620.     rts
  621. *
  622. NonSns:    jmp    0.l        * 元のB_KEYSNSが入る
  623.                 * 飛び先でrtsする
  624.  
  625. SnsPATCH    equ    NonSns+2
  626.  
  627. *--------------------------------------------------------------------
  628. * B_KEYINP
  629.  
  630. KeyInp:
  631.     cmp.b    #MD_Stop,mode
  632.     beq    NonInp        * 完全停止中 -> 通常
  633.     * mode=Active/BuffActive/OnceActive/Pause
  634.     movem.l    d1/a0,-(sp)
  635.     cmp.b    #MD_Pause,mode
  636.     beq    I4        * 休止中 -> 通常キー入力
  637.     * mode=Active/BuffActive/OnceActive
  638.     * 活動中/一時活動中
  639.     bsr    CheckEmpty    * 空?
  640.     beq    @f        * Yes
  641.     * キーバッファー読みだし
  642. *    clr.w    WK_B_KEYSNS    * B_SFTSNSのワークをクリアする : これはASKで×
  643.     and.w    #$fff0,WK_B_KEYSNS    * "OPT2|OPT1|CTRL|SHIFTは押されていない"とする
  644.                     * B_SFTSNSをワークから直接読み取っているソフトのため
  645.     move.l    #SKspc0,d0    * SPACE(scan code)
  646.     bsr    Read        * -> d0.b : d0.l=$35xx
  647.     bra    2f
  648. *
  649. @@:    * 活動中/一時活動中だがキーバッファーがない
  650.     * キーボード読みだし
  651.     * mode=Active/BuffActive/OnceActive
  652.     cmp.b    #MD_OnceActive,mode    * 一時動作?
  653.     bne    I4        * No(動作中)
  654.     * mode=MD_OnceActive
  655.     bsr    Pause        * 休止状態に戻す
  656. I4:    * mode=Active/BuffActive/Pause
  657.     *
  658.     bsr    NonInp        * 元のB_KEYINP -> d0.w.hb:ScanCode , w.lb=ASC
  659.     *
  660.     cmp.b    #MD_BuffActive,mode    * 外部プログラム起動許可?
  661.     beq    2f        * No
  662.     * mode=Active/Pause
  663.     * 外部プログラム起動
  664.     move.l    d0,Key1        * 一旦保存
  665.     move.b    WK_B_KEYSNS+1,d0
  666.     and.w    #$ff0f,d0    * bit3-0のみ : d0.w.hb=Scan,lb=Shift
  667.     beq    @f        * $0000になるキーは外部起動として使えない(V1.61;Condrv対応)
  668.     bsr    SearchEFKey    * 指定キーに相当する外部プログラム指定があるかを調べる
  669.     bne    @f        * そのキーはない
  670.     * 起動キーである
  671.     movem.l    d2/a1-a2,-(sp)    * d0は保存の必要なし、d1/a0がすでに保存ずみ
  672.     move.l    KSD_EF_Exec(a0),a0
  673.     jsr    (a0)        * 外部ルーチン(d0-d2/a0-a2以外は破壊しないこと)
  674.     movem.l    (sp)+,d2/a1-a2
  675.     * V1.5でシフトキー離し待ちはやめた
  676.     * もともとはキー入力時にshift系キーが押されているとまずいことがあるからであるが、
  677.     * バッファーからの読みだし中はshift系=all offにするようにしたので不要になった
  678.     clr.l    Key1        * キー入力は無しの印
  679. @@:    * 起動キーでない
  680.     move.l    Key1,d0        * キーを戻す
  681. 2:    movem.l    (sp)+,d1/a0
  682.     rts
  683.  
  684. NonInp:    jmp    0.l        * 元のB_KEYINPが入る
  685.                 * 飛び先でrtsする
  686.  
  687. InpPATCH    equ    NonInp+2
  688.  
  689. *********************************************************************
  690. * デバイスドライバー:コマンド解析&初期処理
  691. *   デバイスドライバーは(たぶん)常にスーパーバイザーモードで走る。
  692. *********************************************************************
  693.  
  694. Dev_start:
  695.     move.l    a5,Dev_A5        * save リクエストヘッダーアドレス
  696.     rts
  697.  
  698. *********************************************************************
  699.  
  700. Dev_main:
  701.     movem.l    d1-d7/a0-a6,-(sp)    * push register
  702.     move.l    Dev_A5(pc),a5        * a5 <- リクエストヘッダーアドレス
  703.     *
  704.     moveq.l    #0,d0            * for .b -> .l
  705.     move.b    2(a5),d0        * d0.l <- コマンド番号
  706.     add.w    d0,d0            * *2
  707.     lea    comtable(pc),a1
  708.     move.w    (a1,d0.w),d0        * read call offset address
  709.     jsr    (a1,d0.w)        * call subroutines
  710.     *
  711.     move.l    d0,d1
  712.     move.b    d1,3(a5)        * set error code (low)
  713.     lsr.w    #8,d1            * high -> low (8bit)
  714.     move.b    d1,4(a5)        * set error code (high)
  715.     movem.l    (sp)+,d1-d7/a0-a6    * pop register
  716.     rts
  717.  
  718. *********************************************************************
  719.  
  720.     .even
  721. comtable:    * コマンドアドレス(相対アドレス表)
  722.     .dc.w    Dev_init-comtable    * 初期化
  723.     .dc.w    COM_ERR-comtable
  724.     .dc.w    COM_ERR-comtable
  725.     .dc.w    Dev_ioctrl_in-comtable    * ioctrl in = 状態入力
  726.     .dc.w    Dev_Read-comtable    * 入力
  727.     .dc.w    Dev_Rcheck-comtable    * 先行入力
  728.     .dc.w    API_CheckEmpty-comtable    * 入力バッファーチェック
  729.     .dc.w    Clear-comtable        * バッファークリア
  730.     .dc.w    Dev_Write-comtable    * 出力(verify off)
  731.     .dc.w    Dev_Write-comtable    * 出力(verify on)
  732.     .dc.w    API_CheckFull-comtable    * 出力ステータスチェック
  733.     .dc.w    COM_ERR-comtable
  734.     .dc.w    Dev_ioctrl_out-comtable    * ioctrl out = 制御コマンド
  735.     .even
  736.  
  737. *********************************************************************
  738. * エラーコマンド
  739.  
  740. COM_ERR:
  741.     move.w    #$5003,d0    * $50 = 中止&無視 , $03 = コマンドコードが不正
  742.     rts
  743.  
  744. *********************************************************************
  745.  
  746. Dev_Rcheck:            * 先行入力
  747.     bsr    API_Rcheck    * -> d0.b
  748.     move.b    d0,13(a5)
  749.     moveq.l    #0,d0        * no error
  750.     rts
  751.  
  752. *--------------------------------------------------------------------
  753.  
  754. Dev_Read:            * 入力
  755.     lea    API_Read(pc),a0
  756.     bra    @f
  757. Dev_Write:            * 出力(verify on/off)
  758.     lea    API_Write(pc),a0
  759. @@:
  760.     move.l    14(a5),a2    * buffer
  761.     move.l    18(a5),d1    * size : COOKED modeでは常に1(RAW modeでは>=1)
  762.     jsr    (a0)        * Read/Write
  763.     move.l    d0,18(a5)    * 実Read/WriteSizeを返す
  764.     moveq.l    #0,d0        * no error
  765.     rts
  766.  
  767. *--------------------------------------------------------------------
  768.  
  769. Dev_ioctrl_out:            * ioctrl out = 制御コマンド
  770.     move.l    14(a5),a2    * buffer
  771. @@:    move.b    (a2)+,d0    * 1文字コマンド(大文字のみ)
  772.     beq    NonErr        * $00まで
  773.     cmp.b    #'A',d0
  774.     bcs    @b        * APIコマンドは使えなくしておく
  775.     bsr    APImain        * コマンドサーチ
  776.     bra    @b
  777.  
  778. Dev_ioctrl_in:            * ioctrl in = 状態入力
  779. * mode/ver/size/free
  780.     move.l    18(a5),d0    * size
  781.     cmp.l    #KSD_ST_SIZE,d0    * size>=KSD_ST_SIZE?
  782.     bcs    NonErr        * No : sizeが足りない->何も返さない
  783.     move.l    14(a5),a2    * buffer
  784.     * mode
  785.     bsr    API_ReadMode    * d0.l,d1.l,a0破壊
  786.     rol.w    #8,d0        * APIとは順が違うので変換
  787.     move.w    d0,(a2)+
  788.     move.b    #KSD_SEP,(a2)+    * セパレーター
  789.     * version
  790.     move.l    a2,a0        * ここから先はa0に書き込む
  791.     bsr    MakeVerStr    * バージョン番号文字列化
  792.     * buffer size
  793.     move.l    KBsize(pc),d0    * KBsize
  794.     bsr    Store10
  795.     * free
  796.     bsr    API_ReadFree    * d0.l=Free,d1.l,d2.l破壊
  797.     bsr    Store10
  798. NonErr:    * IOCTRL IN/OUTはエラーを返さない
  799.     * サイズを書き込んでも無効(常に0)
  800.     moveq.l    #0,d0        * non error
  801.     rts
  802.  
  803. Store10:
  804.     move.b    #KSD_SEP,(a0)+    * セパレーター
  805.     FPACK    __LTOS        * d0.l(符号つき) -> 10進文字列化
  806.     rts
  807. *
  808. MakeVerStr:
  809. * バージョン番号文字列作成
  810. * a0.l = バッファー
  811.     moveq.l    #0,d0
  812.     move.b    Ver1(pc),d0    * 整数桁
  813.     FPACK    __LTOS        * d0.l(符号つき) -> 10進文字列化
  814.     move.b    #'.',(a0)+    * 小数点
  815.     moveq.l    #0,d0
  816.     move.b    Ver2(pc),d0    * 小数桁
  817.     FPACK    __LTOS        * d0.l(符号つき) -> 10進文字列化
  818.     rts
  819.  
  820. *********************************************************************
  821.  
  822. KEEP_END:    * 常駐:固定部分最後+1
  823.         * これ以降はキーバッファーになる
  824.  
  825. *********************************************************************
  826. *    非常駐ルーチン
  827. *********************************************************************
  828.  
  829. * 外部参照
  830.     * 外部参照するルーチンはプログラムの後部にリンクされる。
  831.     * 従って、常駐後には初期化ルーチンとともに消されるので使えない。
  832.     .xref    _DevCheck
  833.     .xref    _DevCheck2
  834.     .xref    SetDevLink
  835.     .xref    ResetDevLink
  836.     .xref    Atoi
  837.     .xref    Print10
  838.  
  839. *--------------------------------------------------------------------
  840. * 初期化ルーチンは、コマンドラインから起動の時はユーザーモードで、
  841. * デバイスドライバーの時はスーパーバイザーモードで走る(はず)。
  842. * 本当は、デバイスドライバー常駐のものを操作する時のため、
  843. * ここでスーパーバイザーモードにしてからInitSubを呼び出したい。
  844. * しかしそうすると、setblockがエラーを出してしまう。
  845. * したがって、複雑になるが、InitSub中で必要時のみスーパーバイザーにする。
  846. *--------------------------------------------------------------------
  847.  
  848. main:    * 常駐
  849.     lea.l    initsp(pc),sp    * PROGRAM=の時スタックオーバーを起こすので
  850.                 * スタックを変更しておく
  851. *    clr.b    fdev        * コマンドライン組み込み
  852.     bsr    InitSub        * 初期化
  853.     move.w    d0,-(sp)    * exit(?)
  854.     tst.l    d1
  855.     bne    @f
  856.     * 常駐関係以外終了
  857.     DOS    _EXIT2
  858. *
  859. @@:    * デバイスリンクに入り込む
  860.     lea    DevHead(pc),a0
  861.     bsr    SetDevLink
  862.     *
  863.     * 常駐終了
  864.     move.l    d1,-(sp)    * 常駐サイズ
  865.     DOS    _KEEPPR
  866.  
  867. *--------------------------------------------------------------------
  868.  
  869. Dev_init:            * 初期化
  870.     st.b    fdev        * DEVICE=組み込み
  871.     bsr    ChangeLine    * コマンドライン変換
  872.     bsr    PrCRLF        * 1行改行してからメッセージを出す
  873.     *
  874.     lea    cline0(pc),a2
  875.     bsr    InitSub        * 初期化
  876.     tst.l    d1
  877.     beq    @f        * 常駐以外終了
  878.     * 常駐終了
  879.     add.l    #DevHead,d1    * 常駐部最終アドレス
  880.     move.l    d1,14(a5)
  881. @@:
  882.     rts
  883.  
  884. * init時のd0.l<>0は白帯にならずに組み込めないメッセージとなる
  885. *--------------------------------------------------------------------
  886.  
  887. ChangeLine:
  888.     * DEVICE=形式のパラメーターをコマンドライン型に変換する
  889.     * 読み取りルーチン共用化のため
  890.     move.l    18(a5),a0    * 元のコマンドライン
  891.     * 最初の00まではプログラム名なので飛ばす
  892. @@:    tst.b    (a0)+
  893.     bne    @b
  894.     *
  895.     lea    cline(pc),a2    * 変換後ライン
  896.     moveq.l    #0,d1        * length
  897. CL1:    tst.b    (a0)
  898.     beq    CLend        * 0,0で終了
  899. @@:    addq.l    #1,d1        * len++
  900.     move.b    (a0)+,(a2)+
  901.     bne    @b
  902.     * 0をスペースに直す
  903.     move.b #' ',-1(a2)
  904.     bra.s    CL1
  905. *
  906. CLend:    clr.b    (a2)        * EOS
  907.     move.b    d1,cline0
  908.     rts
  909.  
  910. *--------------------------------------------------------------------
  911.  
  912. PrintDevName:
  913. * デバイス名表示
  914. * 改行付き
  915.     bsr    PrintDevName0
  916.     bsr    PrCRLF        * 改行
  917.     rts
  918.  
  919. PrintDevName0:
  920. * デバイス名表示
  921. * エラー表示のため改行しない
  922. * (a0.l/d1.lは壊さないように)
  923.     movem.l    a0/d1,-(sp)
  924.     *
  925.     pea    DeviceMes(pc)
  926.     DOS    _PRINT
  927.     addq.w    #4,sp
  928.     *
  929.     lea.l    DevName-DevHead(a0),a0
  930.     moveq.l    #0,d0        * for .b = .w
  931.     moveq.l    #8-1,d1        * デバイス名は8文字まで
  932. @@:    move.b    (a0)+,d0
  933.     move.w    d0,-(sp)
  934.     DOS    _PUTCHAR
  935.     cmp.w    #' ',(sp)+    * スペースを1つ表示したら終了
  936.     dbeq    d1,@b
  937.     *
  938.     movem.l    (sp)+,d1/a0
  939.     rts
  940.  
  941. *--------------------------------------------------------------------
  942.  
  943. PrintBuff:
  944. * バッファー状態表示
  945. * 常駐している時にその常駐しているルーチンのバッファー状態を表示する
  946. * a0=DevHeadアドレス
  947.     * バッファーアドレス
  948.     pea    BuffAdMes(pc)
  949.     DOS    _PRINT
  950.     addq.w    #4,sp
  951.     move.l    Kbuff-DevHead(a0),d0
  952.     move.l    a0,-(sp)
  953.         lea    SizeAsc(pc),a0
  954.         FPACK    __HTOS
  955.     move.l    (sp)+,a0
  956.     pea    SizeAsc(pc)
  957.     DOS    _PRINT
  958.     addq.w    #4,sp
  959.     * 高位メモリー?
  960.     tst.b    Kbmode-DevHead(a0)
  961.     beq    @f
  962.     pea    MemHigh(pc)    * Yes
  963.     DOS    _PRINT
  964.     addq.w    #4,sp
  965. @@:    bsr    PrCRLF
  966.     *
  967.     * バッファーサイズ
  968.     pea    BuffSzMes(pc)
  969.     move.l    KBsize-DevHead(a0),-(sp)
  970.     bsr    PrMesDec
  971.     * rp
  972.     pea    RpMes(pc)
  973.     move.l    rp-DevHead(a0),-(sp)
  974.     bsr    PrMesDec
  975.     * wp
  976.     pea    WpMes(pc)
  977.     move.l    wp-DevHead(a0),-(sp)
  978.     bsr    PrMesDec
  979.     *
  980.     lea    8*3(sp),sp
  981.     *
  982.     rts
  983.  
  984. PrMesDec:
  985. * メッセージ+10進数表示+改行
  986. * PrMesDec(mes,dec)
  987.     move.l    8(sp),-(sp)
  988.     DOS    _PRINT
  989.     addq.w    #4,sp
  990.     move.l    4(sp),d0
  991.     bsr    Print10
  992. PrCRLF:    * 改行
  993.     pea    CrLf(pc)
  994.     DOS    _PRINT
  995.     addq.w    #4,sp
  996.     rts
  997.  
  998. MemHigh:
  999.     .dc.b    '(高位)',0
  1000.     .even
  1001.  
  1002. *--------------------------------------------------------------------
  1003.  
  1004. PrintMode:
  1005. * 状態表示
  1006. * a0=DevHeadアドレス
  1007.     moveq.l    #KSD_ReadMode,d0
  1008.     move.l    KSD_API(a0),a0        * APIアドレス
  1009.     jsr    (a0)            * d0.l = 状態 : ' '=無視,'E/F','O/B/A/P/S'
  1010.     moveq.l    #4-1,d6            * 4 <- .l = 4*.b
  1011. @@:    bsr    PrStatus        * 再起呼び出しだ!
  1012.     lsr.l    #8,d0            * ' 'は無視される
  1013.     dbra    d6,@b
  1014. PrStatus:
  1015.     move.l    d0,-(sp)
  1016.     lea    ExgFlags-6(pc),a0    * 後で+6するため-6しておく
  1017. @@:    addq.w    #6,a0
  1018.     tst.b    1(a0)            * Option名
  1019.     beq    @f            * 全終了
  1020.     cmp.b    1(a0),d0        * =Option?
  1021.     bne    @b            * No -> check next option
  1022.     move.w    4(a0),a0
  1023.     add.l    #DevHead,a0        * Message(起動プログラム内)
  1024.     pea    (a0)
  1025.     DOS    _PRINT
  1026.     addq.w    #4,sp
  1027. @@:    move.l    (sp)+,d0
  1028.     rts
  1029.  
  1030. *--------------------------------------------------------------------
  1031. * コマンドライン解析(a2=コマンドライン)
  1032. * この中ではa0は壊さないこと(プロセス管理ポインタを参照するため)
  1033.  
  1034. ChkARG:
  1035.     tst.b    (a2)+        * コマンドラインサイズ = 0?
  1036.     bne    arglp        * No
  1037.     * コマンドラインがない(プログラム名のみ)
  1038.     move.w    #$ff00,d0    * 注意(.b=0,.w!=0)
  1039.     rts
  1040. *
  1041. arglp:
  1042. @@:    * 空白飛ばし
  1043.     move.b    (a2)+,d0
  1044.     cmp.b    #' ',d0
  1045.     beq    @b
  1046.     cmp.b    #$09,d0        * TAB
  1047.     beq    @b
  1048.     subq.w    #1,a2        * a2が1つ進んでいるので戻す
  1049.     *
  1050.     tst.b    d0        * end?
  1051.     beq    eos        * Yes
  1052.     * オプションは -? or /?
  1053.     cmp.b    #'-',d0
  1054.     beq    chkopt
  1055.     cmp.b    #'/',d0
  1056.     beq    chkopt
  1057. getarg:    * オプション以外の引数はキーバッファーサイズ指定とみなす
  1058.     * SizeAscにそれを転送
  1059.     lea.l    SizeAsc(opc),a3
  1060. @@:    move.b    (a2)+,d0
  1061.     cmp.b    #' ',d0        * SPCがあったら終わり
  1062.     beq    @f
  1063.     cmp.b    #$09,d0        * TABがあったら終わり
  1064.     beq    @f
  1065.     move.b    d0,(a3)+
  1066.     bne    @b
  1067. eos:    * EOSを入れたら終了(この後にオプションはない)
  1068.     moveq.l    #0,d0        * ok(.b=0,.w=0)
  1069.     rts
  1070. *
  1071. @@:    clr.b    (a3)        * EOS
  1072.     bra    arglp        * オプションチェックに戻る
  1073.  
  1074. chkopt:    * オプションチェック
  1075.     addq.w    #1,a2        * skip '-' or '/'
  1076.     move.b    (a2)+,d0
  1077.     beq    argerr        * -/のみでオプションがない
  1078.     and.b    #%11011111,d0    * 大文字化
  1079.     *
  1080.     lea    ComFlags-6(pc),a6    * 後で+6するため-6しておく
  1081.     tst.b    fdev        * DEVICE=?
  1082.     beq    @f        * no
  1083.     * DEVICE=時
  1084.     lea    DevFlags-6(pc),a6    * 後で+6するため-6しておく
  1085. @@:    addq.w    #6,a6
  1086.     tst.b    1(a6)        * Option名
  1087.     beq    argerr        * 全てのオプションと比較終了 -> 規定外オプション
  1088.     cmp.b    1(a6),d0    * オプションチェック
  1089.     bne    @b        * 不一致
  1090.     tst.b    (a6)        * すでにフラグがセットされている?
  1091.     bne    arglp        * Yes : 飛ばす(2重指定なのでargerrにしてもよい)
  1092.     st.b    (a6)        * セット
  1093.     bra    arglp        * コマンドライン処理へ戻る
  1094.  
  1095. argerr:
  1096.     moveq.l    #-1,d0        * エラー(.b<>0)
  1097.     rts
  1098.  
  1099. *--------------------------------------------------------------------
  1100.  
  1101. ChkVct    macro    vcno,adrs
  1102. * KSDで使っているベクターの書き替えチェック
  1103.     move.w    #vcno,-(sp)
  1104.     DOS    _INTVCG
  1105.     addq.w    #2,sp
  1106.     lea.l    adrs-DevHead(a0),a6    * 飛び先アドレス
  1107.     cmp.l    d0,a6
  1108.     bne    Err_Vect        * ベクターが書き替えられているので常駐解除不可
  1109.     endm
  1110.  
  1111. *--------------------------------------
  1112.  
  1113. InitSub:    * 初期化 -> d0.l:status , d1.l=常駐サイズ
  1114. * a5は壊さないこと
  1115.     move.l    a0,d7        * a0保存
  1116.     lea    SizeAsc(pc),a0
  1117.     bsr    MakeVerStr    * バージョン番号文字列化
  1118.     pea    title1(pc)    * タイトル前半表示
  1119.     DOS    _PRINT
  1120.     pea    SizeAsc(pc)    * バージョン番号
  1121.     DOS    _PRINT
  1122.     pea    title2(pc)    * タイトル後半表示
  1123.     DOS    _PRINT
  1124.     lea    4*3(sp),sp
  1125.     move.l    d7,a0        * a0復帰
  1126.     *
  1127.     bsr    ChkARG        * コマンドライン引数チェック
  1128.     tst.b    d0        * (.wではない)
  1129.     bne    usage        * 引数がおかしい
  1130.     *
  1131.     * このあたりではd0/a2は破壊しないこと
  1132.     *
  1133.     movem.l    d0/a2,-(sp)    * 重要
  1134.     clr.l    -(sp)        * デバイス名格納せず
  1135.     pea    KSDsym(pc)    * 隠しデバイス名
  1136.     bsr    _DevCheck2    * デバイスチェック
  1137.     addq.l    #8,sp
  1138.     move.b    d0,d7        * d7.b :  0=常駐してない(a0=不変=自己メモリーブロック)
  1139.                 *       $ff=常駐している(a0=デバイスヘッダーアドレス=DevHead)
  1140.     movem.l    (sp)+,d0/a2    * 重要
  1141.     *
  1142.     tst.b    rflag        * -r : 常駐解除?
  1143.     beq    keep        * no
  1144. *
  1145. * 常駐解除(device=では絶対に来ない)
  1146. *
  1147.     tst.b    d7            * 常駐している?
  1148.     beq    Err_NoKp        * No -> error
  1149.     *
  1150.     * すでに常駐しているものを解除
  1151.     *
  1152.     * DEVICE=で常駐している時は解除不可
  1153.     lea.l    fdev-DevHead(a0),a1
  1154.     IOCS    _B_BPEEK        * スーパーバイザーの中を覗くことがあるため
  1155.     tst.b    d0
  1156.     bne    Err_Dev            * DEVICE=で組み込まれている
  1157.     *
  1158.     * ここに来るのはコマンドライン常駐の時のみ=ksdは必ずユーザーモード領域にいる
  1159.     * 常駐ロックチェック
  1160.     tst.b    JLock-DevHead(a0)    * =0?
  1161.     bne    Err_Lock        * No:常駐ロック中
  1162.     *
  1163.     * キーベクターが変更されていないか調べる
  1164.     ChkVct    _KFLUSH,k_flush
  1165.     ChkVct    _B_SFTSNS+$100,KeySft
  1166.     ChkVct    _B_KEYSNS+$100,KeySns
  1167.     ChkVct    _B_KEYINP+$100,KeyInp
  1168.     *
  1169.     move.l    ProcAD-DevHead(a0),-(sp)    * このプロセスの先頭アドレス
  1170.     DOS    _MFREE        * 自己プロセスメモリー解放
  1171.     addq.w    #4,sp
  1172.     tst.l    d0
  1173.     bmi    Err_Kai        * なぜかメモリー解放出来ない時
  1174.     *
  1175.     * 以下の処理は、解放したメモリー内にあるプロセスを参照しているので
  1176.     * 非常に危険な処理である。マルチタスク環境下では致命的な問題を起こすかもしれない。
  1177.     tst.b    Kbmode
  1178.     beq    @f
  1179.         * 高位メモリーにあるバッファーを解放
  1180.         move    Kbuff-DevHead(a0),-(sp) * Kbuffのアドレス=*Kbuff
  1181.         DOS    _MFREE            * メモリー解放
  1182.         addq.w    #4,sp
  1183.         tst.l    d0
  1184.         bmi    Err_WkNk        * なぜかメモリー解放出来ない時
  1185.         * エラーが出た場合、メインプロセスがなくワークのみが残ることになる。
  1186.         * 非常によろしくない。一言で言えば手抜きである。
  1187. @@:    * デバイスリンク解除
  1188.     bsr    ResetDevLink    * a0=DevHead
  1189.     *
  1190.     * キーベクター戻し
  1191.     *(これ以降のルーチンでエラーが出ないところで戻しを行う)
  1192.     move.l    KF_PATCH-DevHead(a0),-(sp)
  1193.     move.w    #_KFLUSH,-(sp)
  1194.     DOS    _INTVCS
  1195.     move.l    SftPATCH-DevHead(a0),-(sp)
  1196.     move.w    #_B_SFTSNS+$100,-(sp)
  1197.     DOS    _INTVCS
  1198.     move.l    SnsPATCH-DevHead(a0),-(sp)
  1199.     move.w    #_B_KEYSNS+$100,-(sp)
  1200.     DOS    _INTVCS
  1201.     move.l    InpPATCH-DevHead(a0),-(sp)
  1202.     move.w    #_B_KEYINP+$100,-(sp)
  1203.     DOS    _INTVCS
  1204.     lea    6*4(sp),sp
  1205.     *
  1206.     * 常駐解除正常終了
  1207.     pea.l    MesRelease(pc)    * 解除メッセージ
  1208.     DOS    _PRINT
  1209.     addq.w    #4,sp
  1210.     moveq.l    #0,d1        * 常駐しない
  1211.     moveq.l    #0,d0        * 正常終了:exit(0)
  1212.     rts
  1213.  
  1214. ************************************
  1215. SetVect    macro    adrs,no,patch
  1216.     * キーベクター保存&書き替え
  1217.     pea    adrs(pc)    * これは次のINTVCSのため
  1218.     move.w    #no,-(sp)
  1219.     DOS    _INTVCG
  1220.     move.l    d0,patch
  1221.     DOS    _INTVCS
  1222.     addq.w    #6,sp
  1223.     endm
  1224.  
  1225. SetFlags2Mode:
  1226. * オプションテーブルを見ながらモードを設定する
  1227. * a3,a6破壊 (d1.lは壊さないように)
  1228. * a0=プログラムベースアドレス
  1229.     lea    ExgFlags-6(pc),a6    * 後で+6するため-6しておく
  1230. @@:    addq.w    #6,a6
  1231.     tst.b    1(a6)            * Option名
  1232.     beq    @f            * 全終了
  1233.     tst.b    (a6)            * Optionがセットされている?
  1234.     beq    @b            * No -> check next option
  1235.     * オプションはセットされている
  1236.     * そのオプションをセットするルーチンを呼び出す
  1237.     * 呼び出すのは常駐プログラム内のもの
  1238.     move.w    2(a6),a3        * 起動プログラム内でのアドレスoffset
  1239.     jsr    (a0,a3.w)        * a0+a3.w ; 常駐プログラム内/起動プログラム内
  1240.     move.w    4(a6),a3
  1241.     add.l    #DevHead,a3        * Message(起動プログラム内)
  1242.     pea    (a3)
  1243.     DOS    _PRINT
  1244.     addq.w    #4,sp
  1245.     addq.l    #1,d6            * セットした回数
  1246.     bra    @b
  1247. @@:
  1248.     rts
  1249. ************************************
  1250.  
  1251. AlreadyKeep:
  1252.     * すでに常駐している
  1253.     tst.b    hflag
  1254.     bne    Err_2Kp        * /Hがある -> 2重常駐エラー
  1255.     tst.b    fdev        * 今DEVICE=内で2重常駐しようとしている?
  1256.     bne    Err_2Kp        * Yes -> error(DEVICE=組み込みでは2重常駐エラーにする)
  1257.     *
  1258.     * 常駐時に、コマンドラインからもう一回起動するとモード変更か状態表示になる
  1259.     * a0=常駐しているルーチンのメモリ管理ポインタ
  1260.     clr.l    a1
  1261.     IOCS    _B_SUPER    * super visor mode
  1262.     move.l    d0,-(sp)    * DEVICEの中を覗くため
  1263.     * 状態変更
  1264.     moveq.l    #0,d6
  1265.     bsr    SetFlags2Mode    * Flag -> モード設定
  1266.     tst.l    d6        * モード変更された?
  1267.     bne    StatusOk
  1268.     *
  1269.     * モード変更はしていないので状態表示を行う
  1270.     bsr    PrintDevName    * デバイス名
  1271.     bsr    PrintBuff    * バッファー状態
  1272.     bsr    PrintMode    * 内部状態
  1273. StatusOk:
  1274.     move.l    (sp)+,d0
  1275.     bmi    @f        * 元からsuper visorであった
  1276.     move.l    d0,a1
  1277.     IOCS    _B_SUPER    * user mode
  1278. @@:    *
  1279.     moveq.l    #0,d1        * 常駐しない
  1280.     moveq.l    #0,d0        * 正常終了:exit(0)
  1281.     rts
  1282. *
  1283. * 常駐
  1284. *
  1285. keep:    tst.b    d7        * すでに常駐している?
  1286.     bne    AlreadyKeep    * Yes
  1287.     * KSDは常駐していない
  1288.     tst.w    d0        *(ここまでd0を破壊してはいけない)
  1289.     bne    usage        * バッファー指定がない
  1290.     *
  1291.     * デバイス名を変更する時はここで行う
  1292.     tst.b    kflag        * デバイス名を@KSDにする?
  1293.     beq    @f        * No
  1294.         * @KEY -> @KSD ; 後ろ2文字のみ違う
  1295.         move.w    #('S'<<8)|'D',DevName+2    * ここはワードで書き込める
  1296. @@:    * 同名デバイスもない?
  1297.     movem.l    a0-a2,-(sp)    * 重要
  1298.     pea    DevName(pc)
  1299.     bsr    _DevCheck
  1300.     addq.l    #4,sp
  1301.     movem.l    (sp)+,a0-a2    * 重要
  1302.     tst.b    d0
  1303.     bne    Err_DevUse    * 同名デバイスがある
  1304.     * 同名デバイスもない
  1305.     *
  1306.     * 常駐処理
  1307.     * キーバッファーサイズ取得
  1308.     lea    SizeAsc(pc),a6
  1309.     bsr    Atoi
  1310.     move.l    d0,KBsize
  1311.     move.l    d0,d1        * キーバッファーサイズ保存
  1312.     ble    Err_KbSz    * サイズ指定がおかしい(<=0)
  1313. *
  1314.     tst.b    fdev
  1315.     bne    @f            * -> DEVICE=常駐
  1316.     * コマンドライン常駐時のみ
  1317.     * プログラム起動時にはフリーエリアの全てが起動プログラムに割り当てられているため、
  1318.     * これを必要部分以外解放する。そうしないとMALLOCが効かない。
  1319.     * DEVICE=のときは不要(MALLOC出来る)。
  1320.     * a0=プログラムメモリ管理ポインタ
  1321.     * a1=プログラム終了アドレス+1(.data,.bssを含む)
  1322.     lea    MPSIZ(a0),a0        * メモリー管理ポインタ分を飛ばす
  1323.     move.l    a0,ProcAD        * このプロセスの先頭アドレス(!=DevHead)保存
  1324.     sub.l    a0,a1            * 当プログラムサイズ
  1325.     tst.b    hflag            * 高位メモリー確保?
  1326.     bne    1f            * Yes
  1327.     * 低位メモリー確保の時はそのメモリー分も入れておく必要がある
  1328.     add.l    d1,a1            * d1=キーバッファーサイズ
  1329. 1:    move.l    a1,-(sp)        * 確保する領域サイズ
  1330.     move.l    a0,-(sp)        * 確保する領域の先頭アドレス
  1331.     DOS    _SETBLOCK        * 領域変更
  1332.     addq.w    #4*2,sp
  1333.     tst.l    d0
  1334.     bmi    Err_StBk        * 領域が変更できない時=エラー
  1335.     *
  1336. @@:    move.l    #KEEP_END,Kbuff        * キーバッファーアドレス記憶
  1337.     *
  1338.     tst.b    hflag            * 高位メモリー確保?
  1339.     beq    @f            * No
  1340.         * 高位メモリー確保
  1341.         move.l    d1,-(sp)    * キーバッファーサイズ
  1342.         move.w    #2,-(sp)    * 高位メモリー
  1343.         DOS    _MALLOC2
  1344.         addq.w    #6,sp
  1345.         tst.l    d0
  1346.         beq    Err_Mem        * ワークが確保できない
  1347.         move.l    d0,Kbuff    * アドレス記憶
  1348.         st.b    Kbmode        * 高位メモリーの印
  1349.         moveq.l    #0,d1        * 高位にワークをとったので追加常駐サイズは最小でいい
  1350. @@:    add.l    #KEEP_END-DevHead,d1    * 本体常駐サイズ
  1351.     *
  1352.     * キーベクター保存&書き替え
  1353.     *(これ以降のルーチンでエラーが出ないところで書き替えを行う)
  1354.     SetVect    k_flush,_KFLUSH,KF_PATCH
  1355.     SetVect    KeySft,_B_SFTSNS+$100,SftPATCH
  1356.     SetVect    KeySns,_B_KEYSNS+$100,SnsPATCH
  1357.     SetVect    KeyInp,_B_KEYINP+$100,InpPATCH
  1358.     *
  1359.     pea    MesKeep(OPC)        * 常駐メッセージ
  1360.     DOS    _PRINT
  1361.     addq.w    #4,sp
  1362.     *
  1363.     * フラグによるモードセット(すべてのフラグが有効ではない)
  1364.     * d1.lを壊さないように
  1365.     lea    DevHead(pc),a0        * このプログラム内を参照
  1366.     bsr    PrintDevName        * デバイス名表示
  1367.     bsr    SetFlags2Mode        * Flag -> モード設定
  1368.     moveq.l    #0,d0            * exit(0)
  1369.     rts
  1370.  
  1371. *--------------------------------------
  1372. * エラー処理
  1373. *--------------------------------------
  1374. Err_DevUse:    * デバイス名がすでに使われている
  1375.     lea    DevHead(pc),a0        * このプログラム内を参照
  1376.     bsr    PrintDevName0
  1377.     lea.l    ErrDevUse(pc),a0
  1378.     bra.s    error
  1379. Err_KbSz:    * キーバッファーサイズ指定がおかしい
  1380.     lea.l    ErrIllSize(pc),a0
  1381.     bra.s    error
  1382. Err_StBk:    * SetBlock出来ない
  1383. *    lea.l    ErrCantKpBuff2(pc),a0
  1384. *    bra.s    error
  1385. Err_Mem:    * メモリーが不足している
  1386.     lea.l    ErrCantKpBuff(pc),a0
  1387.     bra.s    error
  1388. Err_NoKp:    * 常駐していないのに解除しようとした
  1389.     lea.l    ErrNoKukikomi(pc),a0
  1390.     bra.s    error
  1391. Err_2Kp:    * 2重常駐
  1392.     lea.l    ErrAlreadySet(pc),a0
  1393.     bra.s    error
  1394. *
  1395. Err_Vect:    * ベクターが書き替えられている
  1396.     lea.l    ErrCantKey(pc),a0
  1397.     bra.s    error
  1398. Err_Dev:    * DEVICE=で組み込まれている
  1399.     lea.l    ErrCantDevice(pc),a0
  1400.     bra.s    @f
  1401. Err_WkNk:    * ワークエリアが解放できない
  1402.     lea.l    ErrCantResBuff(pc),a0
  1403.     bra.s    @f
  1404. Err_Lock:    * 常駐ロックされている
  1405.     lea.l    ErrCantJLock(pc),a0
  1406. @@:    bsr    PrintErr
  1407. Err_Kai:    * 常駐解除不可
  1408.     lea.l    ErrCantRelease(pc),a0
  1409.     bra.s    error
  1410. *
  1411. usage:    * 使用法
  1412.     lea.l    MesUsage(pc),a0
  1413. error:    bsr    PrintErr
  1414.     lea    CrLf(pc),a0
  1415.     bsr    PrintErr
  1416.     moveq.l    #0,d1        * 常駐しない
  1417.     moveq.l    #2,d0        * exit(2)
  1418.     rts
  1419. *
  1420. PrintErr
  1421. * (a0)エラー出力へメッセージ表示
  1422.     move.w    #2,-(sp)    * STDERR
  1423.     pea.l    (a0)
  1424.     DOS    _FPUTS
  1425.     addq.w    #2+4,sp
  1426.     rts
  1427.  
  1428. *********************************************************************
  1429. * メッセージなど
  1430. *********************************************************************
  1431.  
  1432.     .even
  1433. title1        .dc.b    'KeySimulateDriver V',0
  1434. title2        .dc.b    ' Copyright 1997,98 by AIG-Soft',$0d,$0a
  1435. *        .dc.b    '             Debug中 v015',$0d,$0a
  1436.         .dc.b    0
  1437. MesKeep        .dc.b    '組み込みました',$0d,$0a,0
  1438. MesRelease    .dc.b    '解除しました',$0d,$0a,0
  1439. ErrNoKukikomi    .dc.b    '組み込まれていません',$0d,$0a,0
  1440. *
  1441. *ErrCantKpBuff2    .dc.b    'SetBlock不可で'
  1442. ErrCantKpBuff    .dc.b    'キーバッファーが確保できません',0
  1443. ErrAlreadySet    .dc.b    'すでに組み込まれています',0
  1444. ErrIllSize    .dc.b    'キーバッファーサイズが異常です',0
  1445. ErrDevUse    .dc.b    'はすでに使用されています',0
  1446. *
  1447. ErrCantDevice    .dc.b    'DEVICE=で組み込まれています.',0
  1448. ErrCantResBuff    .dc.b    'キーバッファーが解放できません.',0
  1449. ErrCantJLock    .dc.b    '常駐ロックされています.',0
  1450. ErrCantKey    .dc.b    'ベクターが書き替えられています.'    * 次につながる
  1451. ErrCantRelease    .dc.b    'KSDは解除できません',0
  1452. *
  1453. MesUsage    .dc.b    'KSD [/h /r /e /f /p /a /b /c /o /s /k] バッファーサイズ[K]',0
  1454.  
  1455. BuffAdMes    .dc.b    'バッファーアドレス:',0
  1456. BuffSzMes    .dc.b    'バッファーサイズ :',0
  1457. RpMes        .dc.b    'Rp:',0
  1458. WpMes        .dc.b    'Wp:',0
  1459. StopMes        .dc.b    '完全停止状態',$0d,$0a,0
  1460. PauseMes    .dc.b    '休止状態',$0d,$0a,0
  1461. OnceActiveMes    .dc.b    '一時'    * 次につながる
  1462. ActiveMes    .dc.b    '活動状態',$0d,$0a,0
  1463. BuffActiveMes    .dc.b    '外部プログラム起動なし活動状態',$0d,$0a,0
  1464. WFFullMes    .dc.b    '書込Full:古いデータ消去',$0d,$0a,0
  1465. WFMusiMes    .dc.b    '書込Full:無視',$0d,$0a,0
  1466. DeviceMes    .dc.b    'デバイス名:',0
  1467. ClearMes    .dc.b    'キーバッファーをクリアしました'    * 次へつながる
  1468. CrLf        .dc.b    $0d,$0a,0
  1469.  
  1470. *********************************************************************
  1471. * オプション
  1472. *********************************************************************
  1473. * オプション名はコマンド名と同じにする
  1474. * PrintModeでも参照する
  1475.  
  1476.     .even
  1477.         * .dc.b work,フラグキャラクター
  1478.         * .dc.w 処理ルーチンoffset,メッセージoffset(無い時は0,0)
  1479.         * 1オプション分 1+1+2+2=6バイト
  1480. ComFlags:    * コマンドライン時有効フラグ
  1481. rflag        .dc.b    0,'R'    * 常駐解除フラグ
  1482.         .dc.w    0,0
  1483. DevFlags:    * デバイスドライバ時にも有効フラグ
  1484. hflag        .dc.b    0,'H'    * 高位メモリー確保フラグ
  1485.         .dc.w    0,0
  1486. kflag        .dc.b    0,'K'    * デバイス名を@KSDにする
  1487.         .dc.w    0,0
  1488.         * 常駐後にも変更可能なオプション
  1489. ExgFlags:    * 同一系オプションは下の方が優先順位が高い
  1490. cflag        .dc.b    0,'C'    * clear
  1491.         .dc.w    Clear-DevHead,ClearMes-DevHead
  1492. oflag        .dc.b    0,'O'    * Once Active
  1493.         .dc.w    OnceActive-DevHead,OnceActiveMes-DevHead
  1494. aflag        .dc.b    0,'A'    * active
  1495.         .dc.w    Active-DevHead,ActiveMes-DevHead
  1496. bflag        .dc.b    0,'B'    * buff active
  1497.         .dc.w    BuffActive-DevHead,BuffActiveMes-DevHead
  1498. pflag        .dc.b    0,'P'    * pause
  1499.         .dc.w    Pause-DevHead,PauseMes-DevHead
  1500. sflag        .dc.b    0,'S'    * Stop
  1501.         .dc.w    Stop-DevHead,StopMes-DevHead
  1502. eflag        .dc.b    0,'E'    * WriteFull時 無視
  1503.         .dc.w    WFMusi-DevHead,WFMusiMes-DevHead
  1504. fflag        .dc.b    0,'F'    * WriteFull時 古いデータを消す
  1505.         .dc.w    WFFull-DevHead,WFFullMes-DevHead
  1506.         .dc.b    0,0    * end of table
  1507.  
  1508. *********************************************************************
  1509. * 非常駐ルーチンが使うワーク
  1510. *********************************************************************
  1511.     .bss
  1512.     .even
  1513. cline0    .dc.b    0        * 変換後コマンドラインサイズ
  1514. cline    .ds.b    256        * コマンドライン変換
  1515. SizeAsc    .ds.b    96        * キーバッファーサイズを示す文字列
  1516.  
  1517.     .stack
  1518.     .even
  1519.     .ds.l    512        * スタック(コマンドライン起動時のみ使用)
  1520. initsp:
  1521. *********************************************************************
  1522.     .end    main
  1523.